home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Python 1.3 / source code / Tools / freeze / makefreeze.py < prev    next >
Encoding:
Python Source  |  1995-12-17  |  1.8 KB  |  92 lines  |  [TEXT/R*ch]

  1. import marshal
  2.  
  3.  
  4. # Write a file containing frozen code for the modules in the dictionary.
  5.  
  6. header = """
  7. struct frozen {
  8.     char *name;
  9.     unsigned char *code;
  10.     int size;
  11. } frozen_modules[] = {
  12. """
  13. trailer = """\
  14.     {0, 0, 0} /* sentinel */
  15. };
  16. """
  17.  
  18. def makefreeze(outfp, dict):
  19.     done = []
  20.     mods = dict.keys()
  21.     mods.sort()
  22.     for mod in mods:
  23.         modfn = dict[mod]
  24.         try:
  25.             str = makecode(modfn)
  26.         except IOError, msg:
  27.             sys.stderr.write("%s: %s\n" % (modfn, str(msg)))
  28.             continue
  29.         if str:
  30.             done.append(mod, len(str))
  31.             writecode(outfp, mod, str)
  32.     outfp.write(header)
  33.     for mod, size in done:
  34.         outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mod, size))
  35.     outfp.write(trailer)
  36.  
  37.  
  38. # Return code string for a given module -- either a .py or a .pyc
  39. # file.  Return either a string or None (if it's not Python code).
  40. # May raise IOError.
  41.  
  42. def makecode(filename):
  43.     if filename[-3:] == '.py':
  44.         f = open(filename, 'r')
  45.         try:
  46.             text = f.read()
  47.             code = compile(text, filename, 'exec')
  48.         finally:
  49.             f.close()
  50.         return marshal.dumps(code)
  51.     if filename[-4:] == '.pyc':
  52.         f = open(filename, 'rb')
  53.         try:
  54.             f.seek(8)
  55.             str = f.read()
  56.         finally:
  57.             f.close()
  58.         return str
  59.     # Can't generate code for this extension
  60.     return None
  61.  
  62.  
  63. # Write a C initializer for a module containing the frozen python code.
  64. # The array is called M_<mod>.
  65.  
  66. def writecode(outfp, mod, str):
  67.     outfp.write('static unsigned char M_%s[] = {' % mod)
  68.     for i in range(0, len(str), 16):
  69.         outfp.write('\n\t')
  70.         for c in str[i:i+16]:
  71.             outfp.write('%d,' % ord(c))
  72.     outfp.write('\n};\n')
  73.  
  74.  
  75. # Test for the above functions.
  76.  
  77. def test():
  78.     import os
  79.     import sys
  80.     if not sys.argv[1:]:
  81.         print 'usage: python freezepython.py file.py(c) ...'
  82.         sys.exit(2)
  83.     dict = {}
  84.     for arg in sys.argv[1:]:
  85.         base = os.path.basename(arg)
  86.         mod, ext = os.path.splitext(base)
  87.         dict[mod] = arg
  88.     makefreeze(sys.stdout, dict)
  89.  
  90. if __name__ == '__main__':
  91.     test()
  92.